package com.lncg.service.impl;

import com.lncg.entity.BusinessPortConfig;
import com.lncg.mapper.BusinessPortConfigMapper;
import com.lncg.service.IBusinessPortConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 业务端口配置服务实现类
 * 
 * 实现业务端口配置的业务逻辑操作，包括查询端口配置和更新运行状态。
 * 提供异常处理和日志记录，确保操作的可靠性。
 * 
 * @author LNCG
 * @version 1.2.0
 * @since 2024-10-17
 */
@Service
public class BusinessPortConfigServiceImpl implements IBusinessPortConfigService {
    
    /** 日志记录器 */
    private static final Logger logger = LoggerFactory.getLogger(BusinessPortConfigServiceImpl.class);
    
    /** 业务端口配置数据访问对象 */
    @Autowired
    private BusinessPortConfigMapper businessPortConfigMapper;
    
    /**
     * 获取所有启用的业务端口配置
     * 
     * 从数据库中查询所有状态为启用(status=1)的业务端口配置。
     * 这些配置包含了系统需要监听和处理的端口信息。
     * 
     * @return 启用的业务端口配置列表，如果查询失败则返回空列表
     */
    @Override
    public List<BusinessPortConfig> getAllEnabledConfigs() {
        try {
            // 调用数据访问层查询所有启用的配置
            List<BusinessPortConfig> configs = businessPortConfigMapper.selectAllEnabled();
            logger.debug("查询到 {} 个启用的业务端口配置", configs.size());
            return configs;
        } catch (Exception e) {
            logger.error("查询启用的业务端口配置失败: {}", e.getMessage(), e);
            // 异常时返回空列表，避免影响系统稳定性
            return List.of();
        }
    }
    
    /**
     * 根据端口号查询业务端口配置
     * 
     * 通过指定的端口号查询对应的业务端口配置信息。
     * 用于获取特定端口的详细配置，如业务名称、协议类型等。
     * 
     * @param port 要查询的端口号
     * @return 对应的业务端口配置对象，如果不存在或查询失败则返回null
     */
    @Override
    public BusinessPortConfig getConfigByPort(Integer port) {
        try {
            // 根据端口号查询配置信息
            BusinessPortConfig config = businessPortConfigMapper.selectByPort(port);
            if (config != null) {
                logger.debug("查询业务端口配置成功，端口: {}, 业务名称: {}", port, config.getBusinessName());
            } else {
                logger.debug("端口 {} 不存在对应的配置", port);
            }
            return config;
        } catch (Exception e) {
            logger.error("根据端口查询配置失败，端口: {}, 错误: {}", port, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 更新指定端口的运行状态
     * 
     * 更新数据库中指定端口的运行状态，用于标记端口是否正在运行。
     * 当端口启动或停止时，需要同步更新数据库中的状态信息。
     * 
     * @param port 要更新状态的端口号
     * @param isRunning 运行状态：1表示运行中，0表示已停止
     * @return true 更新成功，false 更新失败或端口不存在
     */
    @Override
    public boolean updateRunningStatus(Integer port, Integer isRunning) {
        try {
            // 使用system作为更新者标识，表示由系统自动更新
            String updateBy = "system";
            
            // 执行数据库更新操作
            int result = businessPortConfigMapper.updateRunningStatus(port, isRunning, updateBy);
            boolean success = result > 0;
            
            if (success) {
                // 更新成功，记录成功日志
                String statusText = isRunning == 1 ? "运行" : "停止";
                logger.info("更新端口运行状态成功，端口: {}, 状态: {}", port, statusText);
                return success;
            } else {
                // 更新失败，可能端口不存在或已被删除
                logger.warn("更新端口运行状态失败，端口: {}", port);
            }
            return success;
        } catch (Exception e) {
            // 数据库异常，记录错误日志
            logger.error("更新端口运行状态异常，端口: {}, 状态: {}, 错误: {}", port, isRunning, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 将所有运行中的端口状态更新为停止
     * 
     * 批量更新数据库中所有运行中的端口状态为停止状态。
     * 通常用于系统启动时清理之前可能存在的运行状态，
     * 或者系统关闭时确保所有端口状态正确标记为停止。
     * 
     * @return true 操作成功，false 操作失败
     */
    @Override
    public boolean updateAllRunningStatusToStop() {
        try {
            // 使用system作为更新者标识，表示由系统自动批量更新
            String updateBy = "system";
            
            // 执行批量更新操作，将所有is_running=1的记录更新为0
            int result = businessPortConfigMapper.updateAllRunningStatusToStop(updateBy);
            
            // 记录操作结果
            logger.info("更新所有端口运行状态为停止，影响行数: {}", result);
            return true;
        } catch (Exception e) {
            // 数据库异常，记录错误日志
            logger.error("更新所有端口运行状态为停止异常: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 获取所有启用的端口号列表
     * 
     * 从数据库中查询所有启用的业务端口配置，并提取端口号列表。
     * 这个方法主要用于获取系统中所有需要监听的端口号，
     * 便于进行端口状态检查和端口管理操作。
     * 
     * @return 启用的端口号列表，如果查询失败则返回空列表
     */
    @Override
    public List<Integer> getAllPorts() {
        try {
            // 先查询所有启用的配置
            List<BusinessPortConfig> configs = businessPortConfigMapper.selectAllEnabled();
            
            // 提取端口号列表
            List<Integer> ports = configs.stream()
                    .map(BusinessPortConfig::getPort)  // 提取端口号
                    .collect(Collectors.toList());     // 收集为列表
            
            logger.debug("获取到 {} 个端口配置", ports.size());
            return ports;
        } catch (Exception e) {
            logger.error("获取所有端口失败: {}", e.getMessage(), e);
            // 异常时返回空列表，避免影响系统稳定性
            return List.of();
        }
    }
}
